package com.xhtt.modules.task.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xhtt.modules.cfg.entity.*;
import com.xhtt.modules.cfg.service.*;
import com.xhtt.modules.sys.entity.SysUserEntity;
import com.xhtt.modules.sys.service.SysUserService;
import com.xhtt.modules.task.entity.SuperTaskStep;
import com.xhtt.modules.task.entity.TaskPotTaskStep;
import com.xhtt.modules.task.entity.TaskShipTaskProdStep;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Component("taskStepService")
public class TaskStepService<T extends SuperTaskStep> {
    @Autowired
    private TaskPotTaskStepService taskPotStepService;
    @Autowired
    private TaskShipTaskProdStepService taskShipTaskProdStepService;
    @Autowired
    private CfgTubeInfoService cfgTubeInfoService;
    @Autowired
    private CfgPumpInfoService cfgPumpInfoService;
    @Autowired
    private CfgHoseInfoService cfgHoseInfoService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private CfgHoseProductService hoseProductService;
    @Resource
    private CfgHoseLogService hoseLogService;
    @Autowired
    private CfgTubeProductService tubeProductService;
    @Resource
    private CfgTubeLogService tubeLogService;
    @Autowired
    private CfgPumpProductService pumpProductService;
    @Resource
    private CfgPumpLogService pumpLogService;

    @Autowired
    private TaskStepService taskStepService;

    /**
     * Transactional  和 synchronized 一起会让事务失效，要把同步方法包在事务方法的外面
     */
    public synchronized void synchronizeFunc(List<T> taskSteps, Integer taskId, Integer productId, String productName, SysUserEntity user) {
        taskStepService.updateSteps(taskSteps, taskId, productId, productName, user);
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateSteps(List<T> taskSteps, Integer taskId, Integer productId, String productName, SysUserEntity user) {
        //待更新使用状态的硬管id
        List<Integer> upTubeIds = new ArrayList<>();
        //待更新使用状态的泵id
        List<Integer> upPumpIds = new ArrayList<>();
        //待更新使用状态的软管id
        List<Integer> upHoseIds = new ArrayList<>();


        String taskClass = "";
        if (CollectionUtils.isNotEmpty(taskSteps)) {
            //获取所有可用硬管Id
//            List<Integer> tubeIds = cfgTubeInfoService.list(new LambdaQueryWrapper<CfgTubeInfo>().eq(CfgTubeInfo::getStatus, 1).eq(CfgTubeInfo::getUsed, 0).select(CfgTubeInfo::getId)).stream().map(cfgTubeInfo -> cfgTubeInfo.getId()).collect(Collectors.toList());
            //获取所有可用泵
//            List<Integer> pumpIds = cfgPumpInfoService.list(new LambdaQueryWrapper<CfgPumpInfo>().eq(CfgPumpInfo::getStatus, 1).eq(CfgPumpInfo::getUsed, 0).select(CfgPumpInfo::getId)).stream().map(cfgPumpInfo -> cfgPumpInfo.getId()).collect(Collectors.toList());
            //获取所有可用软管
//            List<Integer> hoseIds = cfgHoseInfoService.list(new LambdaQueryWrapper<CfgHoseInfo>().eq(CfgHoseInfo::getStatus, 1).eq(CfgHoseInfo::getUsed, 0).select(CfgHoseInfo::getId)).stream().map(cfgHoseInfo -> cfgHoseInfo.getId()).collect(Collectors.toList());

            List<TaskPotTaskStep> potSteps = new ArrayList<>();
            List<TaskShipTaskProdStep> shipSteps = new ArrayList<>();
            int step = 1;
            for (SuperTaskStep tt : taskSteps) {
                tt.setStep(step++);

                //判断连接点是否可用  1罐2硬3泵4码5软  业务改了 说不要验证了 用过的也能用 你说是不是日了🐶了
                int conType = tt.getType().intValue();
                Integer conTypeId = tt.getTypeId();
                if (2 == conType) {
//                    if (!tubeIds.contains(conTypeId)) {
//                        throw new RRException(tt.getTypeName() + " 已使用，请重新选择");
//                    }
                    upTubeIds.add(conTypeId);
                } else if (3 == conType) {
//                    if (!pumpIds.contains(conTypeId)) {
//                        throw new RRException(tt.getTypeName() + " 已使用，请重新选择");
//                    }
                    upPumpIds.add(conTypeId);
                } else if (5 == conType) {
//                    if (!hoseIds.contains(conTypeId)) {
//                        throw new RRException(tt.getTypeName() + " 已使用，请重新选择");
//                    }
                    upHoseIds.add(conTypeId);
                }

                if (tt.getClass().isAssignableFrom(TaskPotTaskStep.class)) {
                    TaskPotTaskStep potTaskStep = (TaskPotTaskStep) tt;
                    potTaskStep.setPotTaskId(taskId);
                    potSteps.add(potTaskStep);
                    taskClass = "pot";
                } else if (tt.getClass().isAssignableFrom(TaskShipTaskProdStep.class)) {
                    TaskShipTaskProdStep shipTaskStep = (TaskShipTaskProdStep) tt;
                    shipTaskStep.setShipTaskId(taskId);
                    shipSteps.add(shipTaskStep);
                    taskClass = "ship";
                }

            }
            if ("pot".equals(taskClass)) {
//                TaskPotPlan plan = new TaskPotPlan();
//                plan.setStatus(2);
//                taskPotPlanService.update(plan, new LambdaQueryWrapper<TaskPotPlan>().eq(TaskPotPlan::getId, planId));//设置状态 1待安排2待分配3退回4进行中9完成
                taskPotStepService.remove(new LambdaQueryWrapper<TaskPotTaskStep>().eq(TaskPotTaskStep::getPotTaskId, taskId));//先删之前的记录
                taskPotStepService.saveBatch(potSteps);//保存链接任务步骤
            } else if ("ship".equals(taskClass)) {
//                TaskShipPlan plan = new TaskShipPlan();
//                plan.setStatus(2);
//                taskShipPlanService.update(plan, new LambdaQueryWrapper<TaskShipPlan>().eq(TaskShipPlan::getId, planId));//设置状态 1待安排2待分配3退回4进行中9完成
                taskShipTaskProdStepService.remove(new LambdaQueryWrapper<TaskShipTaskProdStep>().eq(TaskShipTaskProdStep::getShipTaskId, taskId));//先删之前的记录
                taskShipTaskProdStepService.saveBatch(shipSteps);//保存链接任务步骤
            }

        }

        Integer userId = user.getUserId().intValue();
        String deptUser = sysUserService.getUserWithDept(userId);
        //然后把连接点都设为已使用 还要多设置下当前产品
        if (CollectionUtils.isNotEmpty(upTubeIds)) {
            tubeLog(upTubeIds, productId, productName, deptUser);
            cfgTubeInfoService.updateUsed(upTubeIds, productId, productName);
        }
        if (CollectionUtils.isNotEmpty(upPumpIds)) {
            pumpLog(upPumpIds, productId, productName, deptUser);
            cfgPumpInfoService.updateUsed(upPumpIds, productId, productName);
        }
        if (CollectionUtils.isNotEmpty(upHoseIds)) {
            hoseLog(upHoseIds, productId, productName, deptUser);
            cfgHoseInfoService.updateUsed(upHoseIds, productId, productName);
        }
    }

    private void hoseLog(List<Integer> hoseIds, Integer productId, String productName, String deptUser) {
        List<CfgHoseLog> logs = new ArrayList();
        CfgHoseLog log;
        for (Integer hoseId : hoseIds) {
            CfgHoseProduct oldComProduct = hoseProductService.getOne(new LambdaQueryWrapper<CfgHoseProduct>().eq(CfgHoseProduct::getHoseId, hoseId).eq(CfgHoseProduct::getType, 1));
            if (null != oldComProduct && null != oldComProduct.getProductId() && oldComProduct.getProductId().intValue() == productId.intValue()) {
                continue;
            }
            String comProductInfo = (null == oldComProduct.getName() ? "" : oldComProduct.getName()) + " → " + productName;
            log = new CfgHoseLog();
            log.setHoseId(hoseId);
            log.setDeptUser(deptUser);
            log.setPressureLevelInfo("");
            log.setRfidInfo("");
            log.setDateScrapInfo("");
            log.setDateSuppressInfo("");
            log.setComProductInfo(comProductInfo);
            log.setSpareProductInfo("");
            logs.add(log);
        }
        if (CollectionUtils.isNotEmpty(logs)) {
            hoseLogService.saveBatch(logs);
        }
    }

    private void tubeLog(List<Integer> tubeIds, Integer productId, String productName, String deptUser) {
        List<CfgTubeLog> logs = new ArrayList();
        CfgTubeLog log;
        for (Integer tubeId : tubeIds) {
            CfgTubeProduct oldComProduct = tubeProductService.getOne(new LambdaQueryWrapper<CfgTubeProduct>().eq(CfgTubeProduct::getTubeId, tubeId).eq(CfgTubeProduct::getType, 1));
            if (null != oldComProduct && null != oldComProduct.getProductId() && oldComProduct.getProductId().intValue() == productId.intValue()) {
                continue;
            }
            String comProductInfo = (null == oldComProduct.getName() ? "" : oldComProduct.getName()) + " → " + productName;
            log = new CfgTubeLog();
            log.setTubeId(tubeId);
            log.setDeptUser(deptUser);
            log.setRfidInfo("");
            log.setComProductInfo(comProductInfo);
            log.setSpareProductInfo("");
            logs.add(log);
        }
        tubeLogService.saveBatch(logs);
    }

    private void pumpLog(List<Integer> pumpIds, Integer productId, String productName, String deptUser) {
        List<CfgPumpLog> logs = new ArrayList();
        CfgPumpLog log;
        for (Integer pumpId : pumpIds) {
            CfgPumpProduct oldComProduct = pumpProductService.getOne(new LambdaQueryWrapper<CfgPumpProduct>().eq(CfgPumpProduct::getPumpId, pumpId).eq(CfgPumpProduct::getType, 1));
            if (null != oldComProduct && null != oldComProduct.getProductId() && oldComProduct.getProductId().intValue() == productId.intValue()) {
                continue;
            }
            String comProductInfo = (null == oldComProduct.getName() ? "" : oldComProduct.getName()) + " → " + productName;
            log = new CfgPumpLog();
            log.setPumpId(pumpId);
            log.setDeptUser(deptUser);
            log.setRfidInfo("");
            log.setComProductInfo(comProductInfo);
            logs.add(log);
        }
        pumpLogService.saveBatch(logs);
    }

}
